﻿using log4net;
using Quartz;
using Quartz.Impl;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YnPlcDataServer.Variable;

namespace YnPlcDataServer.Scheduler
{
    public class TaskManager
    {
        #region 定义
        private static ILog quartzLog = LogManager.GetLogger(typeof(TaskManager));
        private static TaskManager taskManager = new TaskManager();
        public TaskState taskState;

        public IScheduler scheduler;
        public MySchedulerListener mySchedulerListener { set; get; }
        #endregion

        #region TaskManager
        private TaskManager()
        {
            Init();
        }
        public static TaskManager Instance { get { return taskManager; } }
        private void Init()
        {
            quartzLog.Info("-- TaskManager 初始化 --");
            taskState = TaskState.Shutdown;
            mySchedulerListener = new MySchedulerListener();
        }
        //用 async/await 来处理异步
        public async void TaskStart()
        {
            try
            {
                //MyLogger.Info("开启作业调度....");
                NameValueCollection pars = new NameValueCollection
                {
                    ////scheduler名字
                    //["quartz.scheduler.instanceName"] = "MyScheduler",
                    ////线程池个数
                    //["quartz.threadPool.threadCount"] = "20",
                    ////类型为JobStoreXT,事务
                    //["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz",
                    ////JobDataMap中的数据都是字符串
                    ////["quartz.jobStore.useProperties"] = "true",
                    ////数据源名称
                    //["quartz.jobStore.dataSource"] = "myDS",
                    ////数据表名前缀
                    //["quartz.jobStore.tablePrefix"] = "QRTZ_",
                    ////使用Sqlserver的Ado操作代理类
                    //["quartz.jobStore.driverDelegateType"] = "Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz",
                    ////数据源连接字符串
                    //["quartz.dataSource.myDS.connectionString"] = "Server=[yourserver];Database=quartzDb;Uid=sa;Pwd=[yourpass]",
                    ////数据源的数据库
                    //["quartz.dataSource.myDS.provider"] = "SqlServer",
                    //序列化类型
                    { "quartz.serializer.type", "json" }
                    //["quartz.serializer.type"] = "json",//binary
                    ////自动生成scheduler实例ID，主要为了保证集群中的实例具有唯一标识
                    //["quartz.scheduler.instanceId"] = "AUTO",
                    ////是否配置集群
                    //["quartz.jobStore.clustered"] = "true",
                };
                ISchedulerFactory schedulerFactory = new StdSchedulerFactory();
                scheduler = await schedulerFactory.GetScheduler();
                scheduler.ListenerManager.AddSchedulerListener(mySchedulerListener);
                //5.开启调度器,开始运行
                await scheduler.Start();

                if (PublicVariable.ynDaq != null)
                {
                    if (!string.IsNullOrEmpty(PublicVariable.ynDaq.name) && PublicVariable.ynDaq.interval_inseconds > 0)
                    {
                        //2.创建出来一个具体的作业
                        IJobDetail jobDetail = JobBuilder.Create<GetDataJob>()
                            .WithIdentity("job_" + PublicVariable.ynDaq.name, "group_" + PublicVariable.ynDaq.name)
                            .UsingJobData("daq_id", PublicVariable.ynDaq.daq_id)
                            .Build();
                        //3.创建并配置一个触发器
                        ITrigger trigger = TriggerBuilder.Create()
                            .WithIdentity("trigger_" + PublicVariable.ynDaq.name, "group_" + PublicVariable.ynDaq.name)
                            //.StartAt(runTime)
                            .StartNow()
                            .WithSimpleSchedule(x => x
                                .WithIntervalInSeconds(PublicVariable.ynDaq.interval_inseconds)
                                .RepeatForever())
                            .Build();
                        //4.加入作业调度池中
                        await scheduler.ScheduleJob(jobDetail, trigger);
                    }
                    else
                    {
                        MyLogger.Info("任务加载失败，请检查配置...");
                        quartzLog.Info("任务加载失败，请检查配置...");
                    }
                }
            }
            catch (SchedulerException ex)
            {
                quartzLog.Error(ex.Message);
                MyLogger.Info(ex.Message);
            }
        }
        public void TaskStop()
        {
            //关闭作业调度，将不在执行
            quartzLog.Info("准备关闭作业调度");
            scheduler.Shutdown(true);
            quartzLog.Info("关闭作业调度完成");
            //MyLogger.Info("作业调度关闭...");
        }
        #endregion
    }
}
